home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / plane / _iv_tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  23.0 KB  |  893 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _iv_tree.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. // -------------------------------------------------------------------
  16. //
  17. //  Interval Trees
  18. //
  19. //  Michael Seel   (1990/91)
  20. //
  21. // Implementation as described in
  22. // Kurt Mehlhorn: Data Structures and Algorithms 3, section VIII.5.1.1
  23. //
  24. // -------------------------------------------------------------------
  25.  
  26. #include <LEDA/impl/iv_tree.h>
  27.  
  28.  
  29. // -------------------------------------------------------------
  30. // member functions von iv_tree
  31. // -------------------------------------------------------------
  32.  
  33. // -------------------------------------------------------------
  34. // lrot() , rrot() , ldrot() , rdrot()
  35. // Rotationen am Knoten p
  36.  
  37. void iv_tree::lrot(iv_item p, iv_item q)
  38.  
  39. // p ist der zentrale Knoten um den rotiert wird
  40. // q ist der Vater von p
  41.  
  42.   iv_item h = p->son[_right];
  43.   p->son[_right] = h->son[_left];
  44.   h->son[_left] = p;
  45.    
  46.   if (!q) root=h;
  47.   else
  48.   {
  49.    if ( p == q->son[_left] )   q->son[_left]=h;
  50.    else q->son[_right]=h;
  51.   }; 
  52.   
  53.   p->gr=p->son[_left]->groesse()+p->son[_right]->groesse();
  54.   h->gr=p->groesse()+h->son[_right]->groesse();
  55.  
  56.   reorganize_nodelist(h,p);
  57. }
  58.  
  59. void iv_tree::rrot(iv_item p, iv_item q)
  60.  
  61. // p ist der zentrale Knoten um den rotiert wird
  62. // q ist der Vater von p
  63.  
  64.   iv_item h = p->son[_left];
  65.   p->son[_left] = h->son[_right];
  66.   h->son[_right] = p;
  67.  
  68.   if (!q) root=h;
  69.   else
  70.   {
  71.    if ( p == q->son[_left] ) q->son[_left] = h;
  72.    else q->son[_right] = h; 
  73.   };
  74.  
  75.   p->gr=p->son[_left]->groesse()+p->son[_right]->groesse();
  76.   h->gr=p->groesse()+h->son[_left]->groesse();
  77.  
  78.   reorganize_nodelist(h,p);
  79. }
  80.  
  81. void iv_tree::ldrot(iv_item p, iv_item q)
  82.   iv_item h = p->son[_right];
  83.   iv_item t = h->son[_left];
  84.   rrot(h,p);
  85.   lrot(p,q);
  86. }
  87.  
  88. void iv_tree::rdrot(iv_item p, iv_item q)
  89. {
  90.   iv_item h = p->son[_left];
  91.   iv_item t = h->son[_right];
  92.   lrot(h,p);
  93.   rrot(p,q);
  94. }
  95.  
  96. // ------------------------------------------------------------------
  97. // reorganize_nodelist()
  98. // reorganisiert die nach der Rotation falsch mit Intervallen belegten
  99. // Nodelists entsprechend neu.
  100.  
  101. void iv_tree::reorganize_nodelist(iv_item father, iv_item son)
  102. {
  103.   // nach Aendern des Dictionary-Typs in perfekte BB_trees mit Konstruk-
  104.   // tionsprozedur, die aus einer Liste von n geordneten Knoten ein neu-
  105.   // es Dictionary in Zeit O(n) erzeugt, werden von den folgenden 4 Ite-
  106.   // rationen je 2 in ein Misch_Sort Verfahren abgeaendert und die so
  107.   // auf father und son verteilten Intervalle in Linearzeit in die Kno-
  108.   // ten dictionarys eingebunden
  109.  
  110.   dic_item it;
  111.   nodelist_p fx = new nodelist;
  112.   nodelist_p fy = new nodelist;
  113.   nodelist_p sx = new nodelist;
  114.   nodelist_p sy = new nodelist;
  115.  
  116.   forall_items(it,*(father->x_nodelist())) // father->x_nodelist
  117.                             // liefert Pointer
  118.                             // auf x-Dictionary
  119.       {
  120.      if (split_in_x_interval(father , x_nodelist(father)->key(it)))
  121.         fx->insert(x_nodelist(father)->key(it),x_nodelist(father)->inf(it));
  122.          else
  123.         sx->insert(x_nodelist(father)->key(it),x_nodelist(father)->inf(it));
  124.       };
  125.   // die x-Knotenliste des Vaters wird durchsucht und alle passenden
  126.   // Intervalle der Vater-Knotenliste zugeordnet, Rest an den Sohn
  127.  
  128.   forall_items(it,*(son->x_nodelist())) // son->x_nodelist
  129.                              // liefert Pointer
  130.                             // auf x-Dictionary
  131.       {
  132.      if (split_in_x_interval(father , x_nodelist(son)->key(it))) 
  133.         fx->insert(x_nodelist(son)->key(it),x_nodelist(son)->inf(it));
  134.          else
  135.         sx->insert(x_nodelist(son)->key(it),x_nodelist(son)->inf(it));
  136.       };
  137.   // die x-Knotenliste des Sohns wird durchsucht und alle passenden
  138.   // Intervalle der Vater-Knotenliste zugeordnet, Rest an den Sohn
  139.  
  140.  
  141.   forall_items(it,*(father->y_nodelist())) // father->y_nodelist
  142.                                    // liefert Pointer
  143.                                // auf y-Dictionary
  144.       {
  145.      if (split_in_y_interval(father , y_nodelist(father)->key(it)))
  146.         fy->insert(y_nodelist(father)->key(it),y_nodelist(father)->inf(it));
  147.          else
  148.         sy->insert(y_nodelist(father)->key(it),y_nodelist(father)->inf(it));
  149.       };
  150.   // die y-Knotenliste des Vaters wird durchsucht und alle passenden
  151.   // Intervalle der Vater-Knotenliste zugeordnet, Rest an den Sohn
  152.  
  153.   forall_items(it,*(son->y_nodelist())) // son->y_nodelist
  154.                         // liefert Pointer
  155.                         // auf y-Dictionary
  156.       {
  157.      if (split_in_y_interval(father, y_nodelist(son)->key(it)))
  158.         fy->insert(y_nodelist(son)->key(it),y_nodelist(son)->inf(it));
  159.          else
  160.         sy->insert(y_nodelist(son)->key(it),y_nodelist(son)->inf(it));
  161.       };
  162.   // die y-Knotenliste des Sohns wird durchsucht und alle passenden
  163.   // Intervalle der Vater-Knotenliste zugeordnet, Rest an den Sohn
  164.  
  165.   delete x_nodelist(father);
  166.   delete y_nodelist(father);
  167.   delete x_nodelist(son);
  168.   delete y_nodelist(son);
  169.   // alte Dictionaries werden geloescht und freigegeben
  170.   father->x_nl = fx;
  171.   father->y_nl = fy;
  172.   son->x_nl = sx;
  173.   son->y_nl = sy;
  174.   // Knotenlisten werden mit neu angeordneten Dictionaries intialisiert
  175. }
  176.  
  177.  
  178. // ------------------------------------------------------------
  179. // search()
  180. // nachher: st = ( pk ,..., p1 ) mit 
  181. //          pk = locate(y) , p1 = root 
  182. //          p1 , ... , pk ist Suchpfad nach y
  183. // liefert inneren Knoten k mit key(k) = y , falls existiert
  184. //         0                               , sonst
  185.  
  186. iv_item iv_tree::search(split_item x)
  187.  
  188.   st.clear();
  189.   iv_item p = root;
  190.   iv_item searched = 0;
  191.  
  192.   if (!root) return 0;         // Baum leer
  193.   while (!p->blatt())
  194.   { 
  195.     if (cmp(x,split_value(p))<=0)
  196.     {
  197.       if (cmp(x,split_value(p))==0) searched = p;
  198.       st.push(p);
  199.       p = p->son[_left];
  200.     }
  201.     else
  202.     {
  203.       st.push(p);
  204.       p = p->son[_right];
  205.     }
  206.   }
  207.   st.push(p);
  208.   return searched;
  209. }
  210.  
  211.  
  212. // ------------------------------------------------------------------
  213. // iv_insert(x_typ,x_typ)
  214. // fuegt ein neues Intervall (x,y) in den Baum ein
  215. // gibt Zeiger auf Knoten, in dessen Knotenliste Intervall
  216. // eingefuegt wurde, zurueck.
  217.  
  218. iv_item iv_tree::iv_insert(x_typ x, x_typ y)
  219. {
  220.  if (y<x)
  221.  {
  222.   error_handler(0,"kein Intervall zum einfuegen");
  223.   return 0;
  224.  }
  225.  else
  226.  {
  227.   interval_item x_iv = new interval(x,y);
  228.   interval_item y_iv = new interval(y,x);
  229.   return ins(x_iv,y_iv,++interval_nb);
  230.  }
  231. }
  232.  
  233. // ------------------------------------------------------------------
  234. // ins(interval_item,interval_item,int)
  235. // fuegt den entsprechenden Knoten in die Grundstruktur mit dem 
  236. // entsprechenden split_value und fuegt die beiden Intervalle am
  237. // entsprechenden Knoten in die Knotenlisten
  238.  
  239. iv_item iv_tree::ins(interval_item x, interval_item y, int lfnr) 
  240. {
  241.  iv_item p;
  242.  iv_item t;
  243.  iv_item father;
  244.  split_pair x_pair(x->koo1,-lfnr);
  245.  split_item x_split = &x_pair; 
  246.  
  247.  if (!root)                                     // neuer Baum
  248.  { 
  249.   root = new iv_node(x_split);
  250.   anzahl=1;
  251.  }
  252.  else     // Baum existiert schon !!
  253.   if (root->blatt())
  254.   {
  255.     if (cmp(x_split,split_value(root))<0)
  256.     {
  257.      iv_item help = new iv_node(x_split);
  258.      root = new iv_node(x_split,node,help,root);
  259.      if (x_split->key1==split_value(root->son[_right])->key1)
  260.       nodelist_swap(root , root->son[_right]);
  261.      anzahl++;
  262.     }
  263.     else
  264.      if (cmp(x_split,split_value(root))>0)
  265.      {
  266.       iv_item help = new iv_node(x_split);
  267.       root = new iv_node(split_value(root),node,root,help);
  268.       nodelist_swap(root , root->son[_left]);
  269.       anzahl++;
  270.      }
  271.   }
  272.   else // in Knoten von nicht trivialem Baum wird eingefuegt
  273.   {
  274.     search(x_split);
  275.     p = st.pop();
  276.     father = st.top();
  277.   
  278.     if(cmp(x_split,split_value(p))<0)
  279.     {
  280.      iv_item help = new iv_node(x_split);
  281.      p = new iv_node(x_split,node,help,p);
  282.      // neuer Knoten in p mit split x, x-Blatt links, p-Blatt rechts
  283.      if (x_split->key1==split_value(p->son[_right])->key1)
  284.       nodelist_swap(p , p->son[_right]);
  285.  
  286.      if (cmp(split_value(p),split_value(father))<=0)
  287.        father->son[_left] = p;
  288.      else
  289.        father->son[_right] = p;
  290.      anzahl++;
  291.     }
  292.     else
  293.      if (cmp(x_split,split_value(p))>0)
  294.      {           
  295.       iv_item help = new iv_node(x_split);
  296.       p = new iv_node(split_value(p),node,p,help);
  297.       // neuer Knoten in p mit split p, p-Blatt links, x-Blatt rechts
  298.       nodelist_swap(p , p->son[_left]);
  299.  
  300.       if (cmp(split_value(p),split_value(father))<=0)
  301.         father->son[_left] = p;
  302.       else
  303.         father->son[_right] = p;
  304.       anzahl++;
  305.      }
  306.   }
  307.  
  308.   while (!st.empty())                          // rebalancieren
  309.   { 
  310.     t=st.pop();
  311.     father = st.empty() ? 0 : st.top();
  312.     t->gr++;  
  313.     float i = t->bal();
  314.     if (i < alpha)
  315.     {
  316.      if (t->son[_right]->bal()<=d)
  317.        lrot(t,father);
  318.      else
  319.        ldrot(t,father);
  320.     }
  321.     else
  322.     if (i>1-alpha) 
  323.     {
  324.       if (t->son[_left]->bal()>d)
  325.     rrot(t,father);
  326.       else
  327.     rdrot(t,father);
  328.     }
  329.   }
  330.   
  331.   p = sink(root,x,y,lfnr);
  332.   return p;    
  333. }
  334.  
  335.  
  336. // ------------------------------------------------------------------
  337. // sink()
  338. // laesst Intervall im Baum bis zu dem Knoten v abwaerts gleiten an dem 
  339. // gilt: 1.Komponente von split_value(v) <in> Intervall <Teilmenge von> x_range(v)
  340.  
  341. iv_item iv_tree::sink(iv_item v, interval_item x, interval_item y, int lfnr)
  342. {
  343.    if (v)
  344.    {
  345.      if (split_in_x_interval(v,x))
  346.      {
  347.        if (x_nodelist(v)->lookup(x))
  348.        {
  349.          error_handler(0,"Interval wurde schon eingefuegt!\n");
  350.      split_pair h(x->koo1,-lfnr);
  351.      split_item hi=&h;
  352.      del(hi);
  353.      return 0;
  354.        }
  355.        x_nodelist(v)->insert(x,lfnr);
  356.        y_nodelist(v)->insert(y,lfnr);
  357.        return v;
  358.      }
  359.      else
  360.      {
  361.        if (x->cmp(x->koo2,split_value(v)->key1) < 0)
  362.        { 
  363.      return sink(v->son[_left],x,y,lfnr);
  364.        }
  365.        else
  366.        if (x->cmp(split_value(v)->key1,x->koo1) < 0)
  367.        {
  368.      return sink(v->son[_right],x,y,lfnr);
  369.        }
  370.      }
  371.    }
  372.  
  373.    return 0;
  374. }
  375.  
  376. // ------------------------------------------------------------------
  377. // iv_delete(x_typ,x_typ)
  378. // loescht ein Intervall (x,y) aus dem Baum
  379. // gibt Zeiger auf geloeschtes intervall zurueck 
  380.  
  381. void iv_tree::iv_delete(x_typ x, x_typ y)
  382. {
  383.   if (y<x) 
  384.   {
  385.    error_handler(0,"kein Intervall!\n");
  386.    return;
  387.   }
  388.   else
  389.   if (!root) error_handler(0,"Baum ist leer!\n");
  390.   else
  391.   {
  392.    iv_item v = root;
  393.    interval xi(x,y);
  394.    interval yi(y,x);
  395.    interval_item x_iv = ξ
  396.    interval_item y_iv = &yi; 
  397.    while ( !split_in_x_interval(v,x_iv) && !v->blatt() )
  398.    {
  399.     if (split_value(v)->cmp(y,split_value(v)->key1) < 0)
  400.     {
  401.       v = v->son[_left];
  402.     }
  403.     if (split_value(v)->cmp(split_value(v)->key1,x) < 0) 
  404.     {
  405.       v = v->son[_right];
  406.     }
  407.    }
  408.    // nun ist v der Knoten an dem das Intervall [x,y] abgespeichert sein muesste
  409.    dic_item help1 = x_nodelist(v)->lookup(x_iv);
  410.    dic_item help2 = y_nodelist(v)->lookup(y_iv);
  411.    if (!(help1 && help2))
  412.    {
  413.     error_handler(0,"Intervall nicht vorhanden!\n");
  414.     return;
  415.    }
  416.    else
  417.    {
  418.     split_pair s(x_nodelist(v)->key(help1)->koo1,-x_nodelist(v)->inf(help1));
  419.     split_item search_split = &s; 
  420.     x_nodelist(v)->del_item(help1);
  421.     y_nodelist(v)->del_item(help2);
  422.     if (!del(search_split)) 
  423.       error_handler(1,"Intervall geloescht, Grundstruktur nicht in Ordnung\n");
  424.    } 
  425.   }
  426. }
  427.  
  428.  
  429. // ------------------------------------------------------------------
  430. // del()
  431. // loescht Item it im Baum mit split(it)=y , falls existiert
  432. // gibt 1 zurueck, falls existent und geloescht
  433. // gibt 0 zurueck, falls nicht existent
  434.  
  435. int iv_tree::del(split_item y)
  436. {
  437.   st.clear();
  438.   if (root==0) return 0;                         // s.n.
  439.  
  440.   if (root->blatt())                             // Wurzel loeschen
  441.     if (cmp(y,split_value(root))==0)
  442.     { 
  443.       if (!x_nodelist(root)->empty()) 
  444.      error_handler(1,"noch Intervalle in zu loeschender Wurzel!\n");
  445.       anzahl=0; 
  446.       delete root;
  447.       root=0; 
  448.       return 1; 
  449.     }
  450.     else
  451.     {
  452.      error_handler(0,"Element nicht im Baum\n");  
  453.      return 0;
  454.     }
  455.   else // Baum nicht trivial
  456.   {
  457.     iv_item p,father;
  458.     iv_item pp=search(y);
  459.     if (st.size()==2)                            // Sohn der Wurzel
  460.     { 
  461.       p=st.pop();
  462.       father=st.pop();
  463.  
  464.       int v1 = cmp(y,split_value(father));
  465.       if (cmp(y,split_value(p))!=0)
  466.       {
  467.         return 0;
  468.       }
  469.       anzahl--;
  470.       if (v1<=0)
  471.       {
  472.         root=root->son[_right];
  473.     if(!x_nodelist(father)->empty())
  474.       nodelist_swap(father,root);
  475.       }
  476.       else
  477.       {
  478.         root=root->son[_left];
  479.     if(!x_nodelist(father)->empty())
  480.       {
  481.         if (!root->son[_right]) 
  482.            nodelist_swap(father,root);
  483.             else
  484.         if ((root->son[_right])&&(x_nodelist(father)->size()==2))
  485.             {
  486.            nodelist_swap(father,root->son[_right]);
  487.            reorganize_nodelist(root,root->son[_right]);
  488.             }
  489.             else
  490.            nodelist_swap(father,root->son[_right]);
  491.           } 
  492.       }
  493.       if (!x_nodelist(father)->empty() || !x_nodelist(p)->empty())
  494.     error_handler(1,"Knotenlisten beim Loeschen nicht leer\n");
  495.       delete father;
  496.       delete p;
  497.     }
  498.     else                                // Blatt mit Tiefe >= 2     
  499.     {
  500.       iv_item p=st.pop();
  501.       if (cmp(y,split_value(p))!=0)
  502.       { 
  503.     return 0;
  504.       }
  505.       iv_item q = st.pop();
  506.       father = st.top();
  507.       int v1 = cmp(y,split_value(father));
  508.       int v2 = cmp(y,split_value(q));
  509.       anzahl--;
  510.       if (v1<=0)
  511.         if (v2<=0)
  512.     {
  513.       father->son[_left]=q->son[_right];
  514.       if(!x_nodelist(q)->empty())
  515.         nodelist_swap(q,father->son[_right]);
  516.         }
  517.         else
  518.     {
  519.       father->son[_left]=q->son[_left];
  520.       if(!x_nodelist(q)->empty())
  521.       {
  522.         if (!father->son[_left]->son[_right])
  523.            nodelist_swap(q,father->son[_left]);
  524.             else
  525.         if ((father->son[_left]->son[_right])&&(x_nodelist(q)->size()==2))
  526.             {
  527.            nodelist_swap(q,father->son[_left]->son[_right]);
  528.            reorganize_nodelist(father->son[_left],father->son[_left]->son[_right]);
  529.             }
  530.             else
  531.            nodelist_swap(q,father->son[_left]->son[_right]);
  532.           } 
  533.         }
  534.       else
  535.     if (v2<=0)
  536.     {
  537.       father->son[_right]=q->son[_right];
  538.       if(!x_nodelist(q)->empty())
  539.         nodelist_swap(q,father->son[_right]);
  540.         }
  541.         else
  542.     {
  543.       father->son[_right]=q->son[_left];
  544.       if(!x_nodelist(q)->empty())
  545.       {
  546.         if (!father->son[_right]->son[_right])
  547.            nodelist_swap(q,father->son[_right]);
  548.             else
  549.         if ((father->son[_right]->son[_right])&&(x_nodelist(q)->size()==2))
  550.             {
  551.            nodelist_swap(q,father->son[_right]->son[_right]);
  552.            reorganize_nodelist(father->son[_right],father->son[_right]->son[_right]);
  553.             }
  554.             else
  555.            nodelist_swap(q,father->son[_right]->son[_right]);
  556.           } 
  557.         }
  558.       if (!x_nodelist(p)->empty())
  559.     error_handler(1,"Knotenlisten von p beim Loeschen nicht leer");
  560.       delete p;
  561.       delete q;
  562.     }
  563.   }
  564.   
  565.   // REBALANCIEREN
  566.   iv_item p;
  567.   iv_item father;
  568.   while (!st.empty())
  569.   { p = st.pop();
  570.     father = st.empty() ? 0 : st.top() ;
  571.     p->gr--;              
  572.     float i=p->bal();
  573.     if (i<alpha)
  574.       if (p->son[_right]->bal() <= d)
  575.        lrot(p,father);
  576.       else
  577.        ldrot(p,father);
  578.     else
  579.     if (i>1-alpha)
  580.       if(p->son[_left]->bal() > d)
  581.        rrot(p,father);
  582.       else
  583.        rdrot(p,father);
  584.   }
  585.   return 1;
  586. }
  587.  
  588.  
  589. // ------------------------------------------------------------------
  590. // iv_query(x_typ,x_typ)
  591. // gibt alle Intervalle in einer Liste zurueck, die das mit 
  592. // den Parametern uebergebene Intervall schneiden.
  593.  
  594. interval_list iv_tree::iv_query(x_typ x, x_typ y)
  595. {
  596.  interval_list query_list;
  597.  if (!root)
  598.  {
  599.    error_handler(0,"Baum ist leer");
  600.    return query_list;
  601.  } 
  602.  if (y<x)
  603.  { 
  604.   error_handler(0,"kein Intervall\n");
  605.   return query_list;
  606.  }
  607.  split_pair xp(x,-MAXINT);
  608.  split_pair yp(y,MAXINT);
  609.  split_item xi = &xp;
  610.  split_item yi = &yp;
  611.  iv_item v = root;
  612.  int done=0;
  613.  // Bestimmung der P-Menge mit Hilfe von search-Schleife nach x,
  614.  // unterwegs Abzweig zu search nach y
  615.  // alle zwischen den Pfaden liegenden Knoten werden mit get_all
  616.  // abgearbeitet
  617.  // jeder Knoten wird mit Hilfe von check_iv() nach den in den 
  618.  // Knotenmengen vorhandenen Intervallen, die die Schnittbegingung
  619.  // erfuellen abgearbeitet.
  620.  while (!v->blatt())
  621.  {
  622.    check_nodelist(query_list,v,x,y);
  623.    if (cmp(xi,split_value(v))<=0) // xi <= split(v)
  624.    {
  625.      if ((cmp(yi,split_value(v))>0) && !done)
  626.      {
  627.        y_search(query_list,v->son[_right],yi,x,y);
  628.        done=1;
  629.      }
  630.      else
  631.      {
  632.        if (done)  // klappert den gesamten Unterbaum von v der C-Menge ab
  633.          get_all_in_tree(query_list,v->son[_right]);
  634.      }
  635.      v=v->son[_left];
  636.    }
  637.    else  // xi > split(v)
  638.    {
  639.      v=v->son[_right];
  640.    }
  641.  }
  642.  check_nodelist(query_list,v,x,y);
  643.  return query_list;
  644. }
  645.  
  646. // ------------------------------------------------------------------
  647. // y_search()
  648. // verzweigt vom Knoten v aus, in einen neuen Suchpfad nach dem y-
  649. // Wert des query-Intervalls und fuehrt auch dort die P-checks durch
  650.  
  651. void iv_tree::y_search(interval_list& il, iv_item v, split_item ys,
  652.                x_typ x, x_typ y)
  653. {
  654.  while (!v->blatt())
  655.  {
  656.    check_nodelist(il,v,x,y);
  657.    if (cmp(ys,split_value(v))<=0) // ys <= split(v)
  658.      v=v->son[_left];
  659.    else  // ys > split(v)
  660.    {
  661.      get_all_in_tree(il,v->son[_left]);
  662.      // klappert den gesamten Unterbaum von v der C-Menge ab
  663.      v=v->son[_right];
  664.    }
  665.  }
  666.  check_nodelist(il,v,x,y);
  667. }
  668.   
  669. // ------------------------------------------------------------------
  670. // check_nodelist()
  671. // ueberprueft entsprechend der in MEHLHORN III dargestellten Fall-
  672. // unterscheidung fuer P-Knoten die jeweilige x- oder y-Knotenliste
  673. // oder uebernimmt alle Eintraege.
  674.  
  675. void iv_tree::check_nodelist(interval_list& il, iv_item v, x_typ x, x_typ y)
  676. {
  677.   if ((split_value(v)->cmp(x,split_value(v)->key1)<=0)
  678.   && (split_value(v)->cmp(split_value(v)->key1,y)<=0))
  679.   // dann ist split(v) im query-Intervall, das damit alle Intervalle
  680.   // der Knotenliste schneidet.
  681.     take_all_iv(il,v);
  682.   else
  683.   if (split_value(v)->cmp(x,split_value(v)->key1)>0)
  684.   // Intervall oberhalb des split(v)
  685.     check_y_iv(il,v,x);
  686.   else
  687.   // Intervall unterhalb des split(v)
  688.     check_x_iv(il,v,y);
  689. }
  690.  
  691.  
  692. // ------------------------------------------------------------------
  693. // get_all_in_tree()
  694. // uebernimmt alle im Unterbaum des Knotens v abgespeicherten Inter-
  695. // valle in die uebergebene Liste
  696. // entspricht einer Teilmenge der C-Menge
  697.  
  698. void iv_tree::get_all_in_tree(interval_list& il, iv_item v)
  699. {
  700.   take_all_iv(il,v);
  701.   if (!v->blatt())
  702.   { 
  703.     get_all_in_tree(il,v->son[_left]);
  704.     get_all_in_tree(il,v->son[_right]);
  705.   }
  706. }
  707.  
  708. // ------------------------------------------------------------------
  709. // take_all_iv()
  710. // uebernimmt an einem Knoten alle abgespeicherten Intervalle
  711. // in die mituebergebene Liste.
  712.  
  713. void iv_tree::take_all_iv(interval_list& il, iv_item v)
  714. {
  715.   dic_item it;
  716.   forall_items(it,*(v->x_nodelist()))
  717.   {
  718.     interval_item help = x_nodelist(v)->key(it);
  719.     interval_item ii = new interval(help->koo1, help->koo2);
  720.     il.append(ii);
  721.   }
  722. }
  723.  
  724.  
  725. // ------------------------------------------------------------------
  726. // check_y_iv()
  727. // ueberprueft an einem Knoten alle Intervalle der y-Knotenliste
  728. // auf Schnittbedingung mit dem uebergebenen x-Wert des query-
  729. // Intervalls und haengt bei erfuellter Schnittbedingung das In-
  730. // tervall an die mituebergebene Liste an.
  731.  
  732.   void iv_tree::check_y_iv(interval_list& il, iv_item v, x_typ x)
  733.   { 
  734.       if (!y_nodelist(v)->empty())
  735.       {
  736.     dic_item maxit = y_nodelist(v)->max();
  737.     if (split_value(v)->cmp(y_nodelist(v)->key(maxit)->koo1,x)>=0) 
  738.     {
  739.       dic_item it = maxit;
  740.       int intersect = 1;
  741.       while(it && intersect) 
  742.       {
  743.         if (split_value(v)->cmp(y_nodelist(v)->key(it)->koo1,x)>=0) 
  744.         {
  745.          interval_item help = y_nodelist(v)->key(it); 
  746.          interval_item ii = new interval(help->koo2, help->koo1);
  747.          // die Intervalle der y-Knotenliste haben 1. Komponente
  748.          // y und 2. Komponente x, zur Rueckgabe ist aber die
  749.          // umgekehrte Reihenfolge verlangt.
  750.          il.append(ii);
  751.         }
  752.         else
  753.          intersect = 0;
  754.         it = y_nodelist(v)->pred(it);
  755.           }
  756.         }
  757.       }
  758.   }
  759.  
  760. // ------------------------------------------------------------------
  761. // check_x_iv()
  762. // ueberprueft an einem Knoten alle Intervalle der x-Knotenliste
  763. // auf Schnittbedingung mit dem uebergebenen y-Wert des query-
  764. // Intervalls und haengt bei erfuellter Schnittbedingung das In-
  765. // tervall an die mituebergebene Liste an.
  766.  
  767.   void iv_tree::check_x_iv(interval_list& il, iv_item v, x_typ y)
  768.   { 
  769.       if (!x_nodelist(v)->empty())
  770.       {
  771.     dic_item minit = x_nodelist(v)->min();
  772.     if (split_value(v)->cmp(x_nodelist(v)->key(minit)->koo1,y)<=0) 
  773.     {
  774.       dic_item it = minit; 
  775.       int intersect = 1;
  776.       while(it && intersect) 
  777.       {
  778.         if (split_value(v)->cmp(x_nodelist(v)->key(it)->koo1,y)<=0) 
  779.         {
  780.          interval_item help = x_nodelist(v)->key(it); 
  781.          interval_item ii = new interval(help->koo1, help->koo2);
  782.          // die Intervalle der x-Knotenliste haben 1. Komponente
  783.          // x und 2. Komponente y.
  784.          il.append(ii);
  785.         }
  786.         else
  787.          intersect = 0;
  788.         it = x_nodelist(v)->succ(it);
  789.           }
  790.         }
  791.       }
  792.   }
  793.  
  794.  
  795. //-----------------------------------------------------------------------
  796. // void print_split(iv_item) 
  797. // gibt split_value von p aus
  798.  
  799.   void iv_tree::print_split(iv_item it)   
  800.   { 
  801.     if (it)
  802.       { it->split_value()->print();
  803.         if (it->blatt()) text(" (blatt)\n");
  804.         else text("(Knoten)\n");
  805.        }
  806.     else
  807.       cout << " Knoten leer!\n";
  808.   }
  809.  
  810.  
  811.  
  812.  
  813. //-----------------------------------------------------------------------
  814. // void pr_iv_tree(iv_item p;int blancs)
  815. // gibt den Baum mit Wurzel p aus
  816.  
  817. void iv_tree::pr_iv_tree(iv_item p,int blancs)
  818. {
  819.  if (p==0)
  820.  {
  821.   for (int j=1;j<=blancs;j++) cout << " ";
  822.   cout << "NIL\n";
  823.   return;
  824.  }
  825.  else
  826.  {
  827.   pr_iv_tree(p->son[_left],blancs+10); 
  828.   for (int j=1;j<=blancs;j++) cout << " ";
  829.   
  830.   cout << "(" << p->split_value()->key1 << "," << p->split_value()->key2;
  831.   cout << ") ";
  832.   pr_iv_list(p);
  833.   pr_iv_tree(p->son[_right],blancs+10); 
  834.  }
  835. }
  836.  
  837. //-----------------------------------------------------------------------
  838. // void pr_iv_list(iv_item p)
  839. // gibt die Intervalliste eines Knotens p aus
  840.  
  841. void iv_tree::pr_iv_list(iv_item p)
  842. {
  843.   dic_item it;
  844.   forall_items(it,*(p->x_nodelist()))
  845.   { cout << "[" << x_nodelist(p)->key(it)->koo1;
  846.     cout << "," << x_nodelist(p)->key(it)->koo2 << "]"; 
  847.     cout << "#" << x_nodelist(p)->inf(it) << ";";
  848.    }
  849.   cout << "  *  ";
  850.   forall_items(it,*(p->y_nodelist()))
  851.   { cout << "[" << y_nodelist(p)->key(it)->koo1;
  852.     cout << "," << y_nodelist(p)->key(it)->koo2<< "]"; 
  853.     cout << "#" << y_nodelist(p)->inf(it) << ";";
  854.    }
  855.   cout << "\n";
  856. }
  857.  
  858. //-----------------------------------------------------------------------
  859. // void pr_list()
  860. // gibt die zurueckgegebene Intervalliste der query aus
  861.  
  862. void iv_tree::pr_list(interval_list& il)
  863. {
  864.   cout << "Liste: \n";
  865.   if(il.empty()) cout << " leer\n";
  866.   list_item it;
  867.   forall_list_items(it,il)
  868.     il.contents(it)->print(); 
  869. }
  870.     
  871.  
  872. //-----------------------------------------------------------------------
  873. // Funktion fuer Destruktor
  874. //-----------------------------------------------------------------------
  875.   
  876. void iv_tree::deltree(iv_item p)
  877. {
  878.  if (p)
  879.  {
  880.   if (!p->blatt())
  881.   {
  882.    deltree(p->son[_left]);
  883.    deltree(p->son[_right]);
  884.   }
  885.   delete(p);
  886.  }
  887. }
  888.